/********************************************************************************
 * Copyright (c)2016-2020, ShenZhen WanJiaAn Technology CO.,LTD.
 * All Rights Reserved.
 *
 * File Name     : DevLed.c
 * Author        : joki.zhu
 * Date          : 2019-10-16
 *
 * Record        :
 * 1.Date        : 2019-10-16
 *   Author      : joki.zhu
 *   Modification: Created file
 ********************************************************************************/ 
#include "DevLed.h"
#include "ProductManager.h"
#include "app_common.h"
#include "hi_uartmsg.h"
#include "DevSocSub.h"

static LED_MODULE_S gs_Led;
static int mcu_ctrl_led_state = -1;
static char red_state = -1;
static char blue_state = -1;

static void mcu_ctrl_red_led(int state)
{
    unsigned char val = 0;
    
    if (state != red_state)
    {
        if (PRODUCT_MODEL_B1 == ProductGetHandle()->ProductModel) 
        {
            if (state) {
                val = 0x2;
                SocSubSetLedState(val);
            } else {
                val = 0x0;
                SocSubSetLedState(val);
            }
        }
        else if (PRODUCT_MODEL_B5 == ProductGetHandle()->ProductModel)
        {
            if (state) {
                val = 0x1;
                SocSubSetLedState(val);
            } else {
                val = 0x0;
                SocSubSetLedState(val);
            }
            GpioReset(PRODUCT_GPIO_LED_BLUE);
        }
        red_state = state;
        blue_state = -1;
    }
}

static void mcu_ctrl_blue_led(int state)
{
    unsigned char val = 0;
    
    if (state != blue_state)
    {
        if (PRODUCT_MODEL_B1 == ProductGetHandle()->ProductModel)
        {
            if (state) {
                val = 0x1;
                SocSubSetLedState(val);
            } else {
                val = 0x0;
                SocSubSetLedState(val);
            }
        }
        else if (PRODUCT_MODEL_B5 == ProductGetHandle()->ProductModel)
        {
            if (state) {
                GpioSet(PRODUCT_GPIO_LED_BLUE);
            } else {
                GpioReset(PRODUCT_GPIO_LED_BLUE);
            }
            SocSubSetLedState(0x0);
        }

        blue_state = state;
        red_state = -1;
    }    
}

static void led_ctrl(LED_TYPE_E ledType, int bEnable)
{
	int ret = -1;
	
	switch (ledType)
	{
		case LED_TYPE_RED:
            if (bEnable) {
                mcu_ctrl_red_led(1);            
            } else {
                mcu_ctrl_red_led(0);          	
            }
			break;
		case LED_TYPE_BLUE:
			if (bEnable) {
                mcu_ctrl_blue_led(1);			
			} else {
                mcu_ctrl_blue_led(0);			
			}	
			break;
		default:
			LOGW("The led type %d is error!\n", ledType);
			break;
	}
}

static void *tskLedProc(void *args)
{
    SET_THREAD_NAME("tskLedProc");
    pthread_detach(pthread_self());
    
	while (gs_Led.m_Loop)
	{
		if (0 == gs_Led.bEnable)
		{
			usleep(100 * 1000);
			led_ctrl(gs_Led.m_CurLed, 0);
			continue;
		}
		
		switch (gs_Led.m_State)
		{
			case LED_STATE_ON:
				led_ctrl(gs_Led.m_CurLed, 1);
				usleep(100 * 1000);
				break;
			case LED_STATE_OFF:
				led_ctrl(gs_Led.m_CurLed, 0);
				usleep(100 * 1000);
				break;
			case LED_STATE_BLINK:
				led_ctrl(gs_Led.m_CurLed, 0);
				usleep(300 * 1000);
				led_ctrl(gs_Led.m_CurLed, 1);
				usleep(300 * 1000);
				break;
			case LED_STATE_FAST_BLINK:
				led_ctrl(gs_Led.m_CurLed, 0);
				usleep(150 * 1000);
				led_ctrl(gs_Led.m_CurLed, 1);
				usleep(150 * 1000);
				break;
			case LED_STATE_CROSS_BLINK:
				led_ctrl(LED_TYPE_RED, 0);
				usleep(150 * 1000);
				led_ctrl(LED_TYPE_BLUE, 1);
				usleep(150 * 1000);
				led_ctrl(LED_TYPE_BLUE, 0);
				usleep(150 * 1000);
				led_ctrl(LED_TYPE_RED, 1);
				usleep(150 * 1000);				
				break;
			case LED_STATE_UPGRADE:
			    {
			        int i = 0;
			        int num = 3;
			        for (i = 0; i < num; i++)
			        {
        				led_ctrl(gs_Led.m_CurLed, 1);
        				usleep(100 * 1000);
        				led_ctrl(gs_Led.m_CurLed, 0);
        				usleep(100 * 1000);			        
			        }
			        sleep(1);
			    }
				break;				
		}
	}
	pthread_exit(0);
}

int LedInit(void)
{
	int ret = 0;
	
	memset(&gs_Led, 0, sizeof(LED_MODULE_S));
	gs_Led.bInit = 0;
	gs_Led.bEnable = 1;
	gs_Led.m_CurLed = LED_TYPE_RED;
	gs_Led.m_State = LED_STATE_ON;
	gs_Led.m_Level = LED_LEVEL_LOW;
	gs_Led.m_Loop = 1;
	gs_Led.m_Pid = 0;
	pthread_mutex_init(&gs_Led.m_Lock, NULL);
	
	ret = pthread_create(&gs_Led.m_Pid, NULL, tskLedProc, NULL);
	if (ret != 0) {
		LOGE("Fail to pthread_create");
		return -1;
	}
	
	gs_Led.bInit = 1;
	LOGD("LedInit success\n");
	
	return 0;
}

int LedSet(LED_TYPE_E ledType, LED_STATE_E ledState, LED_LEVEL_E ledLevel)
{
	if (gs_Led.bInit == 0 || ledType > LED_TYPE_NONE || ledState > LED_STATE_NONE || ledLevel > LED_LEVEL_NONE) {
		return -1;
	}

	char *ledTypeStr[] = {
		"LED_TYPE_RED",
		"LED_TYPE_BLUE",
		"LED_TYPE_NONE"
	};	
	
	char *ledStateStr[] = {
		"LED_STATE_ON",
		"LED_STATE_OFFF",
		"LED_STATE_BLINK",
		"LED_STATE_FAST_BLINK",
		"LED_STATE_CROSS_BLINK",
		"LED_STATE_UPGRADE",
		"LED_STATE_NONE"
	};	
	
	//printf("LedSet %s is %s\n", ledTypeStr[ledType], ledStateStr[ledState]); //debug

    /* recovery led level */
    if (ledType == LED_TYPE_NONE && ledState == LED_STATE_NONE) {
        gs_Led.m_Level = ledLevel;
        return 0;
    }

    /* set led status */
    if (ledLevel >= gs_Led.m_Level)
    {
    	gs_Led.m_CurLed = ledType;
    	gs_Led.m_State = ledState;
    	gs_Led.m_Level = ledLevel;
    }

	
	return 0;
}

int LedSwitch(int bEnable)
{
	if (gs_Led.bInit == 0) {
		return -1;
	}
	
	gs_Led.bEnable = bEnable;
	
	return 0;
}

int LedDeinit(void)
{
	int ret = -1;
	
	if (gs_Led.bInit == 0) {
		return -1;
	}
	
	if (gs_Led.m_Pid > 0)
	{
		gs_Led.m_Loop = 0;
		ret = pthread_cancel(gs_Led.m_Pid);
		if (ret != 0) {
			LOGE("failt to pthread_cancel tskLedProc");
			return -1;
		}
		gs_Led.m_Pid = -1;
	}
	
	gs_Led.bInit = 0;
	
	return 0;
}


